package org.alys114.springcloud.pmember.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.alys114.springcloud.pmember.client.BookClient;
import org.alys114.springcloud.pmember.client.RestResult;
import org.alys114.springcloud.pmember.entities.Member;
import org.alys114.springcloud.pmember.service.MemberService;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: Vincent.chan
 * @date: 2019/9/23 10:01
 * @version: v1.0
 * @Description: TODO<描述>
 */

// 在浏览器上如果其他域名(端口不同也算)的url发送请求，浏览器自身的安全策略是不允许的，所以,我们要设置 @CrossOrigin 来解决跨域访问的问题
// @CrossOrigin 表示对所有来源请求都允许
@Controller
@CrossOrigin
@DefaultProperties(defaultFallback = "defaultFallback")
public class MemberController {
    @Resource
    private MemberService memberService;

    //这是负载均衡客户端 , 这是Ribbon的核心组件
    //@Resource
    //private LoadBalancerClient loadBalancerClient;

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/check")
    @ResponseBody
    public Map checkMobile(String mobile) {
        Map result = new HashMap<String,String>();

        try {
            result.put("code", "0");
            result.put("msg", "success");
            Member member = memberService.checkByMobile(mobile);
            result.put("data", member);
        } catch (Exception e) {
            e.printStackTrace();
            result.put("code",e.getClass().getSimpleName());
            result.put("msg",e.getMessage());
        }
        return result;

    }

    @GetMapping("/test")
    @ResponseBody
    //@HystrixCommand(fallbackMethod = "fallback")
    @HystrixCommand
    public String test(Integer bid){
        /*
        服务间通信
        - 方式1：
        最简单的情况是使用SpringCloud内置的RestTemplate对象(不推荐)
        RestTemplate底层进行的Http传输就是使用的Apache HttpClient组件
        [缺点] 访问的url固定，无法做到负载均衡
        */
        //RestTemplate restTemplate = new RestTemplate();
        //String s = restTemplate.getForObject("http://10.0.0.1:8007/info?bid=" + bid, String.class);

        /*
         方式2：使用 Robbin 进行客户端负载均衡（不实用，因为有更简便的方法 >> 使用注解）
         */
        //RestTemplate restTemplate = new RestTemplate();
        //ServiceInstance serviceInstance = loadBalancerClient.choose("pbook");
        //String host = serviceInstance.getHost();
        //int port = serviceInstance.getPort();
        //String s = restTemplate.getForObject("http://" + host +":"+ port + "/info?bid=" + bid, String.class);

        /*
         方式3：使用注解的方式,简化操作
         */
        // uri = http://[被调用方在Eureka的注册名称]/xxx
        String s = restTemplate.getForObject("http://pbook/info?bid=" + bid, String.class);
        System.out.println(s);
        return s;
    }

    /* 服务降级处理类，对应 test(Integet bid) 方法
     * 服务降级的方法，必须与目标方法保持一致（参数、返回值）
     */
    private String fallback(Integer bid){
        return "当前服务不可用，请稍后再试......";
    }

    /*
     * 默认系统降级方法
     */
    private String defaultFallback(){
        return "[默认系统降级]当前服务不可用，请稍后再试......";
    }


    @Resource
    private BookClient bookClient;

    @GetMapping("/test1")
    @ResponseBody
    public String test1(Integer bid) {
        RestResult info = bookClient.getInfo(bid);
        return info.getData().getName();
    }
}
